﻿using System;
using System.Xml.Serialization;
using System.IO;
using System.Collections.Generic;

namespace Browis.Utils
{
    /// <summary>
    /// 序列化静态类
    /// </summary>
    public static class SerializableHelper
    {
        /// <summary>
        /// 序列化类容器
        /// </summary>
        private static IDictionary<Type, XmlSerializer> SerializeContainer = new Dictionary<Type, XmlSerializer>();

        /// <summary>
        /// 序列化
        /// </summary>
        /// <param name="_object"></param>
        /// <returns></returns>
        public static string Serialize<T>(T _object)
        {
            if (_object == null)
            {
                throw new ArgumentNullException("_object");
            }

            if (!SerializeContainer.ContainsKey(typeof(T)))
            {
                SerializeContainer[typeof(T)] = new XmlSerializer(typeof(T));
            }

            XmlSerializer serializer = SerializeContainer[typeof(T)];

            // Create a TextWriter to write with.
            TextWriter writer = new StringWriter();

            // Serialize the object, and close the TextWriter
            serializer.Serialize(writer, _object);
            writer.Close();
            return writer.ToString();
        }

        /// <summary>
        /// 序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="filename"></param>
        /// <param name="_object"></param>
        public static void Serialize<T>(string filename, T _object)
        {
            if (string.IsNullOrEmpty(filename))
            {
                throw new ArgumentNullException("filename");
            }
            if (_object == null)
            {
                throw new ArgumentNullException("_object");
            }

            if (!SerializeContainer.ContainsKey(typeof(T)))
            {
                SerializeContainer[typeof(T)] = new XmlSerializer(typeof(T));
            }

            XmlSerializer serializer = SerializeContainer[typeof(T)];

            // Create a FileStream to write with.
            Stream writer = new FileStream(filename, FileMode.Create);
            // Serialize the object, and close the TextWriter
            serializer.Serialize(writer, _object);
            writer.Close();
        }


        /// <summary>
        /// 反序列化
        /// </summary>
        /// <param name="strXml"></param>
        /// <returns></returns>
        public static T Deserialize<T>(string strXml)
        {
            if (string.IsNullOrEmpty(strXml))
            {
                throw new ArgumentNullException("strXml");
            }

            if (!SerializeContainer.ContainsKey(typeof(T)))
            {
                SerializeContainer[typeof(T)] = new XmlSerializer(typeof(T));
            }

            // Create an instance of the XmlSerializer.
            XmlSerializer serializer = SerializeContainer[typeof(T)];

            TextReader reader = new StringReader(strXml);
            T model = (T)serializer.Deserialize(reader);
            reader.Close();

            return model;
        }

        /// <summary>
        /// 反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="filename"></param>
        /// <returns></returns>
        public static T DeserializeFile<T>(string filename)
        {
            if (string.IsNullOrEmpty(filename))
            {
                throw new ArgumentNullException("filename");
            }
            if (!File.Exists(filename))
            {
                throw new FileNotFoundException(filename);
            }

            if (!SerializeContainer.ContainsKey(typeof(T)))
            {
                SerializeContainer[typeof(T)] = new XmlSerializer(typeof(T));
            }

            // Create an instance of the XmlSerializer.
            XmlSerializer serializer = SerializeContainer[typeof(T)];

            // Reading the XML document requires a FileStream.
            Stream reader = new FileStream(filename, FileMode.Open);

            // Call the Deserialize method to restore the object's state.
            T t = (T)serializer.Deserialize(reader);

            reader.Close();

            return t;
        }


    }
}
